home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
oop_tp55.zip
/
LIST2_3.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1990-03-08
|
7KB
|
262 lines
program Listing2_3;
uses Crt; { for KeyPressed }
const
ON = true;
OFF = false;
MinR = 0; { Minimum number of counts in an analog input }
MaxR = 4095; { Maximum number of counts in an analog input }
var
f : text; {predefined file type}
type
Resolution = 0..4095; { Range for analog input }
String12 = string[12];
Tag = object
TagNumber : String12;
procedure Init( ATag : String12 );
end;
Digital = object(Tag)
Status : boolean;
procedure Init( ATag : String12; AStatus : boolean );
procedure PutStatus( AStatus : boolean );
function GetStatus : boolean;
end;
Analog = object(Tag)
Value : Resolution;
ZeroVal : real;
MaxVal : real;
Slope : real;
procedure Init( ATag : String12; AValue : Resolution;
Min, Max : real );
procedure PutValue( AValue : real );
function GetValue : real;
end;
DOutput = object(Digital)
end;
Pump = object(DOutput)
FlowRate : real;
procedure Init( ATag : String12; AStatus : boolean; AFlow : real );
function Flow : real;
end;
DInput = object(Digital)
Setpoint : real;
Reading : real;
procedure PutSetpoint( NewSetpoint : real );
end;
HiSwitch = object(DInput)
procedure Init( ATag : string;
ASetpoint : real;
AReading : real);
procedure PutReading( NewReading : real );
end;
LoSwitch = object(DInput)
procedure Init( ATag : string;
ASetpoint : real;
AReading : real);
procedure PutReading( NewReading : real );
end;
procedure Tag.Init( ATag : String12 );
begin
TagNumber := ATag;
end;
procedure Digital.Init( ATag : String12; AStatus : boolean );
begin
Tag.Init( ATag );
Status := AStatus;
end;
procedure Digital.PutStatus( AStatus : boolean );
begin
Status := AStatus;
end;
function Digital.GetStatus : boolean;
begin
if Status = on then
writeln( f, TagNumber, ' is ON.' )
else
writeln( f, TagNumber, ' is OFF.' );
GetStatus := Status;
end;
procedure Pump.Init( ATag : String12; AStatus : boolean; AFlow : real );
begin
Digital.Init( ATag, AStatus );
FlowRate := AFlow;
end;
function Pump.Flow : real;
begin
Flow := FlowRate;
end;
procedure Analog.Init( ATag : String12;
AValue : Resolution;
Min, Max : real );
begin
Tag.Init( ATag );
Value := AValue;
MaxVal := Max;
ZeroVal := Min;
Slope := (Max-Min)/(MaxR-MinR);
end;
procedure Analog.PutValue( AValue : real );
begin
if AValue > MaxVal then
AVAlue := MaxVal
else
if AValue < ZeroVal then
AValue := ZeroVal;
Value := Round((AValue - ZeroVal)/Slope);
end;
function Analog.GetValue : real;
begin
GetValue := Slope*Value + ZeroVal;
end;
procedure DInput.PutSetpoint( NewSetpoint : real );
begin
Setpoint := NewSetpoint;
end;
procedure LoSwitch.Init( ATag : string;
ASetpoint : real;
AReading : real);
begin
Tag.Init( ATag );
DInput.PutSetpoint( ASetpoint );
PutReading( AReading );
end;
procedure LoSwitch.PutReading( NewReading : real );
begin
Reading := NewReading;
if Reading <= Setpoint then
Status := true
else
Status := false;
end;
procedure HiSwitch.Init( ATag : string;
ASetpoint : real;
AReading : real);
begin
Tag.Init( ATag );
DInput.PutSetpoint( ASetpoint );
PutReading( AReading );
end;
procedure HiSwitch.PutReading( NewReading : real );
begin
Reading := NewReading;
if Reading >= Setpoint then
Status := true
else
Status := false;
end;
{ HtToPSI converts a height (of a column of water) into a pressure.
The math is pretty simple: A column of water 2.31 feet high exerts
a force of one pound per square inch at the bottom. }
function HtToPSI( Height : real ) : real;
begin
HtToPSI := Height/2.31;
end;
{ FlowToDeltaHt converts a flow into (or out of) our system into a
change in height in the tank.
The math is as follows: Divide the flow, in gpm, by 7.48 gal/cu.ft.
to get the number of cubic feet pumped per minute. Divide this
number by the volume of 1 vertical foot of the tank, which is
the radius squared times 'pi' (15*15*3.1416). }
function FlowToDeltaHt( Flow : real ) : real;
begin
FlowToDeltaHt := Flow/(7.48 * 706) ;
end;
var
LT100,
FT100 : Analog;
PSL100 : LoSwitch;
PSH100 : HiSwitch;
EY100 : Pump;
time : integer;
begin
{ If no file name is passed to the program, then ParamStr(1)
will be the null string, which will cause Assign to output
to the standard output (the screen). If a file name is
passed, the output will be saved in the file for later
reference. }
Assign( f, ParamStr(1) );
Rewrite( f );
LT100.Init( 'LT100', 512, 50, 250 );
FT100.Init( 'FT100', 2048, 0, 10000 );
PSL100.Init( 'PSL100', 60, HtToPSI(LT100.GetValue) );
PSH100.Init( 'PSH100', 75, HtToPSI(LT100.GetValue) );
EY100.Init( 'EY100', off, 8000);
time := 0;
repeat
Inc( time ); { increment the time }
{ First, adjust the reading in LT-100 by reducing the level in
LT100.Value by an amount corresponding to the flow out of the
system. We do this by fetching the value of FT100, converting
it to a height in the tank, and subtracting from the actual
height... }
LT100.PutValue( LT100.GetValue - FlowToDeltaHt(FT100.GetValue) );
{ We take the result and update the switches }
PSL100.PutReading( HtToPSI(LT100.GetValue) );
PSH100.PutReading( HtToPSI(LT100.GetValue) );
{Let's publish the level in the tank...}
writeln( f, 'Level in tank is ', LT100.GetValue:2:2, ' feet at minute ', time );
{ If the pressure is too low, turn on the pump }
if PSL100.GetStatus = on then
EY100.PutStatus( ON );
{ If the pressure is too high, turn off the pump }
if PSH100.GetStatus = on then
EY100.PutStatus( OFF );
LT100.PutValue( LT100.GetValue + FlowToDeltaHt( EY100.Flow ));
until KeyPressed;
Close ( f );
end.